import java.util.HashMap;
import java.util.Map;


public class No039 {
    /**
     * 数组中有一个数字出现的次数超过数组长度的一半，请找出这个数字。
     * 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
     * 由于数字2在数组中出现了5次，超过数组长度的一半，因此输出2。如果不存在则输出0。
     */
    public int MoreThanHalfNum_Solution(int[] array) {
        if (array.length == 1) return array[0];
        Map<Integer, Integer> map = new HashMap<>();
        for (int value : array) {
            if (map.containsKey(value)) {
                int count = map.get(value) + 1;
                if (count > array.length / 2) return value;
                map.replace(value, count);
            } else map.put(value, 1);
        }
        return 0;
    }

    // 该数字出现次数比其他所有数字出现的和多
    public int MoreThanHalfNum_Solution2(int[] array) {
        if (array.length == 0) return 0;
        int preValue = array[0];//用来记录上一次的记录
        int count = 1;//preValue出现的次数（相减之后）
        for (int i = 1; i < array.length; i++) {
            if (array[i] == preValue)
                count++;
            else {
                count--;
                if (count == 0) {
                    preValue = array[i];
                    count = 1;
                }
            }
        }
        int num = 0;//需要判断是否真的是大于1半数
        for (int value : array)
            if (value == preValue)
                num++;
        return (num > array.length / 2) ? preValue : 0;
    }

    // Partition
    public int MoreThanHalfNum_Solution3(int[] array) {
        if (array.length == 0) return 0;
        int lo = 0, hi = array.length - 1, mid = lo + ((hi - lo) >> 1);
        int index = SortQuick.Partition(array, lo, hi);
        while (index != mid) {
            if (index > mid) {
                hi = index - 1;
            } else {
                lo = index + 1;
            }
            index = SortQuick.Partition(array, lo, hi);
        }
        int result = array[mid];

        int num = 0;//需要判断是否真的是大于1半数
        for (int value : array)
            if (value == result)
                num++;
        return (num > array.length / 2) ? result : 0;
    }
}
